package com.pet.aop;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.pet.entity.UserDO;
import com.pet.mapper.UserMapper;
import com.pet.utils.UserContextUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;

/**
 * @ClassDescription: 切面类
 * @JdkVersion: 1.8
 * @Created: 2025-05-19 14:53
 */
@Aspect
@Component
public class TokenAspect {

    /**
     * 切点方法
     */
    @Pointcut(value = "execution(* com.pet.controller.*.*(..))")
    public void pointcut(){}

    /**
     * @Around 环绕通知
     * @Around("pointcut()") 可以理解为对这个方法进行环绕通知
     * ProceedingJoinPoint 参数 用于环绕通知，
     * 使用proceed()方法来执行目标方法，可以理解为 前置通知结束 开始执行使用该注解的方法。
     */
    @Around("pointcut()")
    public Object doBefore(ProceedingJoinPoint joinPoint) throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        assert attributes != null;
        HttpServletRequest request = attributes.getRequest();
        HttpServletResponse response = attributes.getResponse();
        String token = request.getHeader("token");
        String path = request.getRequestURI().substring(request.getContextPath().length()).replaceAll("[/]+$", "");
        if (CollectionUtil.newArrayList("/login", "/registerCheck", "/register").contains(path)) {
            return joinPoint.proceed();
        }
        UserMapper userMapper = SpringUtil.getBean(UserMapper.class);
        LambdaQueryWrapper<UserDO> queryWrapper = Wrappers.<UserDO>lambdaQuery()
                .eq(UserDO::getToken, token);
        UserDO userDO = userMapper.selectOne(queryWrapper);
        if (Objects.isNull(userDO)) {
            response.setContentType("application/json;charset=utf-8");
            response.setStatus(401);
            response.getWriter().write("请先登录");
            return null;
        } else {
            UserContextUtil.addCurrentUser(userDO);
            //5.放行
            return joinPoint.proceed();
        }
    }

}


